{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n",
      "/home/leon/miniconda3/lib/python3.6/importlib/_bootstrap.py:219: RuntimeWarning: compiletime version 3.5 of module 'tensorflow.python.framework.fast_tensor_util' does not match runtime version 3.6\n",
      "  return f(*args, **kwds)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import json\n",
    "from keras.models import Model\n",
    "from keras.layers import Input, Conv2D, SeparableConv2D, Activation, BatchNormalization\n",
    "from keras import backend as K\n",
    "from collections import OrderedDict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def format_decimal(arr, places=6):\n",
    "    return [round(x * 10**places) / 10**places for x in arr]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "DATA = OrderedDict()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### pipeline 15"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "random_seed = 10015\n",
    "data_in_shape = (7, 7, 1)\n",
    "\n",
    "layers = [\n",
    "    Conv2D(2, (3,3), padding='valid', strides=(1,1)),\n",
    "    BatchNormalization(epsilon=1e-03, axis=-1, center=True, scale=True),\n",
    "    Activation('relu'),\n",
    "    SeparableConv2D(2, (3,3), padding='same', strides=(1,1)),\n",
    "    BatchNormalization(epsilon=1e-03, axis=-1, center=True, scale=True)\n",
    "]\n",
    "\n",
    "input_layer = Input(shape=data_in_shape)\n",
    "x = layers[0](input_layer)\n",
    "for layer in layers[1:-1]:\n",
    "    x = layer(x)\n",
    "output_layer = layers[-1](x)\n",
    "model = Model(inputs=input_layer, outputs=output_layer)\n",
    "\n",
    "np.random.seed(random_seed)\n",
    "data_in = 2 * np.random.random(data_in_shape) - 1\n",
    "\n",
    "# set weights to random (use seed for reproducibility)\n",
    "weights = []\n",
    "for i, w in enumerate(model.get_weights()):\n",
    "    np.random.seed(random_seed + i)\n",
    "    if i == 5 or i == 12:\n",
    "        # std should be positive\n",
    "        weights.append(np.random.random(w.shape))\n",
    "    else:\n",
    "        weights.append(2 * np.random.random(w.shape) - 1)\n",
    "model.set_weights(weights)\n",
    "\n",
    "result = model.predict(np.array([data_in]))\n",
    "data_out_shape = result[0].shape\n",
    "data_in_formatted = format_decimal(data_in.ravel().tolist())\n",
    "data_out_formatted = format_decimal(result[0].ravel().tolist())\n",
    "\n",
    "DATA['pipeline_15'] = {\n",
    "    'input': {'data': data_in_formatted, 'shape': data_in_shape},\n",
    "    'weights': [{'data': format_decimal(w.ravel().tolist()), 'shape': w.shape} for w in weights],\n",
    "    'expected': {'data': data_out_formatted, 'shape': data_out_shape}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### export for Keras.js tests"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "filename = '../../test/data/pipeline/15.json'\n",
    "if not os.path.exists(os.path.dirname(filename)):\n",
    "    os.makedirs(os.path.dirname(filename))\n",
    "with open(filename, 'w') as f:\n",
    "    json.dump(DATA, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"pipeline_15\": {\"input\": {\"data\": [0.263717, -0.720003, 0.8268, -0.92253, 0.462425, 0.244446, -0.124898, -0.811324, 0.354873, 0.801179, 0.564291, -0.355745, 0.644611, 0.859794, -0.560491, -0.788843, -0.963575, -0.638994, 0.405345, 0.176622, -0.153501, 0.998311, 0.944831, 0.536878, 0.033269, -0.435141, -0.309305, 0.602218, 0.537614, 0.254239, 0.37362, -0.505583, -0.948316, 0.939032, 0.149339, -0.197973, -0.224213, 0.028595, -0.795155, -0.951132, 0.729428, 0.59133, 0.864157, -0.620287, -0.843726, -0.920702, -0.496038, 0.822909, 0.890635], \"shape\": [7, 7, 1]}, \"weights\": [{\"data\": [0.263717, -0.720003, 0.8268, -0.92253, 0.462425, 0.244446, -0.124898, -0.811324, 0.354873, 0.801179, 0.564291, -0.355745, 0.644611, 0.859794, -0.560491, -0.788843, -0.963575, -0.638994], \"shape\": [3, 3, 1, 2]}, {\"data\": [-0.296519, 0.572188], \"shape\": [2]}, {\"data\": [-0.983721, 0.040472], \"shape\": [2]}, {\"data\": [0.524698, 0.474407], \"shape\": [2]}, {\"data\": [-0.040091, -0.549528], \"shape\": [2]}, {\"data\": [0.14783, 0.198852], \"shape\": [2]}, {\"data\": [0.584586, -0.737099, -0.575981, -0.959165, 0.528879, -0.767619, -0.669488, -0.008686, 0.12889, -0.992103, 0.481899, -0.20261, 0.81531, 0.405667, -0.500145, -0.349009, 0.426971, 0.662575], \"shape\": [3, 3, 2, 1]}, {\"data\": [-0.470443, -0.553947, -0.078266, 0.730533], \"shape\": [1, 1, 2, 2]}, {\"data\": [-0.389418, 0.767296], \"shape\": [2]}, {\"data\": [0.550792, -0.229108], \"shape\": [2]}, {\"data\": [0.304147, -0.117505], \"shape\": [2]}, {\"data\": [0.453662, -0.506543], \"shape\": [2]}, {\"data\": [0.296361, 0.407461], \"shape\": [2]}], \"expected\": {\"data\": [0.219238, -0.677985, -2.58341, 0.360723, -1.275605, -0.228328, 0.392925, -0.896873, 0.417156, -0.834217, -0.415627, -0.135939, -1.048117, 0.123814, -1.744815, 0.405, -1.046245, 0.134385, -1.565544, 0.23616, -0.536067, -0.116145, -0.326501, -0.122216, -0.831852, 0.144915, -1.604822, 0.340508, 0.254569, -0.499731, -0.276547, -0.252957, -1.31593, 0.320422, -2.877554, 0.97416, -2.366373, 0.673242, -0.941472, -0.02324, -0.42089, -0.15502, -1.318147, 0.341634, -2.617689, 0.895466, 0.085786, -0.218687, 1.115638, -0.832125], \"shape\": [5, 5, 2]}}}\n"
     ]
    }
   ],
   "source": [
    "print(json.dumps(DATA))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
